package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.app.config.StringRedisConfig;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.aip.AipFaceTemplate;
import com.itheima.autoconfig.im.HuanXinTemplate;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.autoconfig.sms.SmsTemplate;
import com.itheima.domain.db.Log;
import com.itheima.domain.db.User;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.FocusUser;
import com.itheima.domain.mongo.Friend;
import com.itheima.domain.mongo.UserLike;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.db.UserService;
import com.itheima.service.mongo.FocusUserService;
import com.itheima.service.mongo.FriendService;
import com.itheima.service.mongo.UserLikeService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import com.itheima.vo.*;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.util.*;

@Component
public class UserManager {

    @DubboReference
    UserService userService;

    @Autowired
    SmsTemplate smsTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @DubboReference
    UserInfoService userInfoService;

    @Autowired
    AipFaceTemplate aipFaceTemplate;

    @Autowired
    OssTemplate ossTemplate;

    @Autowired
    HuanXinTemplate huanXinTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @DubboReference
    private FocusUserService focusUserService;
    @DubboReference
    private UserLikeService userLikeService;
    @Autowired
    private StringRedisConfig stringRedisConfig;
    @DubboReference
    private FriendService friendService;

    public Long save(User user){
        return userService.save(user);
    }

    public User findByMobile(String mobile){
        return userService.findByMobile(mobile);
    }

    public void sendCode(String phone) {
        //1.随机生成验证码(6位)
        String code = RandomUtil.randomNumbers(6);
        //TODO 项目上线注释掉
        code = "123456";

        //2.调用模板发送验证码
        //TODO 项目上线放开注释
        //smsTemplate.sendSms(phone,code);

        //3.将验证码存入redis且设置时效
        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE+phone,code, Duration.ofMinutes(5));
    }

    public ResponseEntity regAndLogin(Map<String, String> map) {
        //1.获取用户输入的手机号和验证码
        String phone = map.get("phone");
        String requestCode = map.get("verificationCode");

        //2.判断验证码是否输入正确,若不正确提示用户(500)
        ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
        String redisCode = valueOperations.get(ConstantUtil.SMS_CODE + phone);

        if (!StrUtil.equals(requestCode,redisCode)) {
            //return ResponseEntity.status(500).body("请输入正确的验证码");
            return ResponseEntity.status(500).body(ErrorResult.codeError());
        }

        //3.调用service判断手机号有无注册过(有无用户)
        User user = userService.findByMobile(phone);
        boolean isNew;

        if (user!=null) {
            //3.1若存在,isNew=false
            //查询redis中 看看是否有这个字段  如果有的话就返回提示
            isNew = false;

            if (stringRedisConfig.stringRedisTemplate2().hasKey("Free1"+user.getId())){
                return ResponseEntity.status(500).body("此用户处于登录冻结状态");
            }
        }else{
            //3.2若不存在,isNew=true,保存用户
            isNew = true;

            user=new User();
            user.setMobile(phone);
            user.setPassword(ConstantUtil.INIT_PASSWORD);

            Long id = userService.save(user);//远程调用时用户和service中用户不是同一个
            user.setId(id);

            //往环信上注册用户
            huanXinTemplate.register("HX"+id);
        }

        //4.调用jwt的工具类生成token
        //4.1 去除密码
        user.setPassword(null);

        //4.2 将用户转成map,生成token
        String token = JwtUtil.createToken(BeanUtil.beanToMap(user));

        //5.为了方便以后获取用户数据,将token作为key,用户数据作为value放入redis中且设置时效30天
        valueOperations.set(ConstantUtil.USER_TOKEN+token, JSON.toJSONString(user),Duration.ofDays(30));
        //5.1 删除之前的验证码
        stringRedisTemplate.delete(ConstantUtil.SMS_CODE+phone);

        //6.构建返回值isNew和token(使用map)
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("isNew",isNew);
        resultMap.put("token",token);

        //7.往rabbit中发送操作的日志
        Log log = new Log();
        log.setUserId(user.getId());
        log.setLogTime(DateUtil.formatDate(new Date()));
        log.setPlace("北京顺义");
        log.setEquipment("华为");
        log.setType(isNew?"0102":"0101");

        //rabbitTemplate.convertAndSend("","tanhua.log",log);
        rabbitTemplate.convertAndSend("tanhua.log",log);

        return ResponseEntity.ok(resultMap);
    }

    public ResponseEntity saveUserInfo(UserInfo userInfo, String token) {
        //1.通过token获取用户
        User user = findUserFromToken(token);

        //2.当用户为空,返回401
        if (user == null) {
            return ResponseEntity.status(401).body(null);
        }

        //3.封装userInfo的id
        userInfo.setId(user.getId());

        //4.远程调用service完成保存操作
        userInfoService.save(userInfo);
        return ResponseEntity.ok(null);
    }

    public User findUserFromToken(String token) {
        if (StrUtil.isNotBlank(token)) {
            //从redis获取用户json数据
            String userJson = stringRedisTemplate.opsForValue().get(ConstantUtil.USER_TOKEN + token);
            if (StrUtil.isNotBlank(userJson)) {
                //将json转成user
                return JSON.parseObject(userJson, User.class);
            }
        }
        return null;
    }

    public ResponseEntity saveUserInfoHead(MultipartFile headPhoto, String token) throws IOException {
        //1.从token中获取用户
        User user = findUserFromToken(token);
        //2.若用户为空,返回401
        if (user == null) {
            return ResponseEntity.status(401).body(null);
        }

        //3.判断头像是否是人脸
        if (!aipFaceTemplate.detect(headPhoto.getBytes())) {
            //4.若不是,返回500和提示信息
            return ResponseEntity.status(500).body(ErrorResult.faceError());
        }

        //5.将图片保存到oss上,返回地址
        String url = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());

        //6.封装userInfo
        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId());
        userInfo.setAvatar(url);//用户头像
        userInfo.setCoverPic(url);//用户信息背景

        //7.调用service更新用户信息
        userInfoService.update(userInfo);
        return ResponseEntity.ok(null);
    }

    public UserInfoVo findUserInfoById(Long userID) {
        //1.远程调用service查询userInfo
        UserInfo userInfo = userInfoService.findById(userID);

        //2.创建UserInfoVo
        UserInfoVo vo = new UserInfoVo();

        //3.拷贝属性
        BeanUtils.copyProperties(userInfo,vo);

        //4.返回vo
        return vo;
    }

    public ResponseEntity updateUserInfo(UserInfo userInfo, String token) {
        /*//1.从token中获取用户
        User user = findUserFromToken(token);
        //2.若用户为空,返回401
        if (user == null) {
            return ResponseEntity.status(401).body(null);
        }*/

        User user = UserHolder.get();

        //3.给userInfo设置用户id
        userInfo.setId(user.getId());

        //4.远程调用service完成更新操作
        userInfoService.update(userInfo);
        return ResponseEntity.ok(null);
    }
    public ResponseEntity sendVerificationCode(String token) {
        //1.从token中获取用户
        User user = findUserFromToken(token);
        //2.若用户为空,返回401
        if (user == null) {
            return ResponseEntity.status(401).body(null);
        }
        String phone = user.getMobile();

        //1.随机生成验证码(6位)
        String code = RandomUtil.randomNumbers(6);
        //TODO 项目上线注释掉
        // code = "123456";

        //2.调用模板发送验证码
        //TODO 项目上线放开注释
        smsTemplate.sendSms(phone,code);
        System.out.println(code);

        //3.将验证码存入redis且设置时效
        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE+phone,code, Duration.ofMinutes(5));
        return null;
    }

    public ResponseEntity checkVerificationCode(String requestCode, String token) {

        //1.从token中获取用户
        User user = findUserFromToken(token);
        String phone = user.getMobile();
        //从redis获取发送的验证码
        String code = stringRedisTemplate.opsForValue().get(ConstantUtil.SMS_CODE + phone);
        //对比系统发送的验证码和用户输入的验证码
        boolean verification = code.equals(requestCode);
        //输入错误的话，给出友好提示
        if (verification == false){
            return ResponseEntity.status(500).body("笨比，输错了");
        }
        HashMap<String, Boolean> map = new HashMap<>();
        map.put("verification",verification);
        return ResponseEntity.ok(map);
    }

    public ResponseEntity savePhone(String phone) {
        Long id = UserHolder.get().getId();
        userService.savePhone(phone,id);
        return null;
    }

    /**
     * 互相喜欢,喜欢,粉丝统计
     *
     * @return
     */
    public ResponseEntity counts() {
        Long userId = UserHolder.get().getId();
        // 新建vo
        UserLikeCountVo vo = new UserLikeCountVo();
        // 喜欢
        Long loveCount = 0L;
        List<UserLike> all = userLikeService.findAll(userId);
        if (CollUtil.isNotEmpty(all)) {
            for (UserLike userLike : all) {
                loveCount++;
            }
        }

        vo.setLoveCount(loveCount);
        // 互相喜欢
        Long eachLikeCount = 0L;

        List<Friend> friendList = friendService.findAllById(userId);
        if (CollUtil.isNotEmpty(friendList)) {
            for (Friend friend : friendList) {
                eachLikeCount++;
            }
        }

        vo.setEachLoveCount(eachLikeCount);
        // 粉丝
        Long fanCount = 0L;
        List<FocusUser> focusUserList = focusUserService.findAllById(userId);
        if (CollUtil.isNotEmpty(focusUserList)) {
            for (FocusUser focusUser : focusUserList) {
                fanCount++;
            }
        }
        vo.setFanCount(fanCount);
        return ResponseEntity.ok(vo);
    }

    /**
     * 互相喜欢、喜欢、粉丝、谁看过我 - 翻页列表
     *
     * @param pageNum
     * @param pageSize
     * @param type
     * @return
     */
    public ResponseEntity findByPage(Integer pageNum, Integer pageSize, Integer type) {
        System.out.println(type);
        // 1.获取userId
        Long userId = UserHolder.get().getId();
        // 获取当前页数据
        PageBeanVo pageBeanVo = friendService.findContactsByPage(userId, pageNum, pageSize);
        // 互相喜欢
        if (type == 1) {

            // 获取其中的集合
            List<Friend> friendList = (List<Friend>) pageBeanVo.getItems();
            // 遍历封装
            List<UserInfo> userInfoList = new ArrayList<>();
            if (CollUtil.isNotEmpty(friendList)) {
                for (Friend friend : friendList) {
                    UserInfo userInfo = userInfoService.findById(friend.getFriendId());


                    userInfoList.add(userInfo);
                }
            }
            pageBeanVo.setItems(userInfoList);
        }
        if (type == 2) {
            List<UserLike> userLikeList = userLikeService.findAll(userId);
            // 遍历封装
            List<UserInfo> userInfoList = new ArrayList<>();
            if (CollUtil.isNotEmpty(userLikeList)) {
                for (UserLike userLike : userLikeList) {
                    UserInfo userInfo = userInfoService.findById(userLike.getLikeUserId());
                    userInfoList.add(userInfo);
                }
            }
            pageBeanVo.setItems(userInfoList);
        }
        if (type == 3) {
            List<FocusUser> focusUserList = focusUserService.findAllById(userId);
            // 遍历封装
            List<UserLikeVo> vos = new ArrayList<>();
            if (CollUtil.isNotEmpty(focusUserList)) {
                for (FocusUser focusUser : focusUserList) {
                    UserInfo userInfo = userInfoService.findById(focusUser.getFocusUserId());
                    UserLikeVo vo = new UserLikeVo();
                    vo.setId(userInfo.getId());
                    vo.setAvatar(userInfo.getAvatar());
                    vo.setNickname(userInfo.getNickname());
                    vo.setGender(userInfo.getGender());
                    vo.setAge(userInfo.getAge());
                    vo.setCity(userInfo.getCity());
                    vo.setEducation(userInfo.getEducation());
                    vo.setMarriage(userInfo.getMarriage());
                    vos.add(vo);
                }
            }
            pageBeanVo.setItems(vos);
        }

        return ResponseEntity.ok(pageBeanVo);
    }

    /**
     * 粉丝-喜欢
     *
     * @param userId
     */
    public void fans(String userId) {

        // 1.获取当前用户的id
        Long toUserId = UserHolder.get().getId();
        /*// 保存喜欢数据
        UserLike userLike = new UserLike();
        userLike.setCreated(System.currentTimeMillis());
        userLike.setUserId(toUserId);
        userLike.setLikeUserId(Long.parseLong(userId));
        userLikeService.save(userLike);*/


        // 判断是否互相喜欢
        //if (userLikeService.isLove(toUserId, Long.parseLong(userId))) {
        // 2.调用service
        friendService.addContact(toUserId, Long.parseLong(userId));
        // 调用环信模板完成好友添加
        huanXinTemplate.addContacts("HX" + toUserId, "HX" + userId);
        // 3.删除已添加好友的
        focusUserService.delete(toUserId, Long.parseLong(userId));
        //}


    }

    /**
     * 粉丝 喜欢 - 取消
     *
     * @param userId
     */
    public void unLike(String userId) {
        // 获取当前用户id
        Long toUserId = UserHolder.get().getId();
        long uid = Long.parseLong(userId);
        userLikeService.delete(toUserId, uid);
        friendService.delete(toUserId, uid);


    }


}
